package com.eascs.web.o2o.report.util;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.HashSet;
import java.util.Set;

import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;
import org.apache.commons.net.ftp.FTPReply;

import com.eascs.app.log.Logger;
import com.eascs.app.log.LoggerFactory;
import com.eascs.web.o2o.report.dto.FtpConfig;

public class FtpUtil {
	private final static Logger logger = LoggerFactory.getLogger(FtpUtil.class);
	
	private static FTPClient ftp;
	
	public static boolean connectFtp(FtpConfig config) throws Exception{
		ftp = new FTPClient();
		boolean flag = false;

		if (config.getPort() == null) {
			ftp.connect(config.getIpAddr(), 21);
		} else {
			ftp.connect(config.getIpAddr(), config.getPort());
		}

		ftp.login(config.getUserName(), config.getPwd());
		ftp.setFileType(FTPClient.BINARY_FILE_TYPE);

		int reply = ftp.getReplyCode();
		if (!FTPReply.isPositiveCompletion(reply)) {
			ftp.disconnect();
			return flag;
		}      
		
		flag = true;
		
        return flag;
    }
    
    /**
     * 关闭ftp连接
     */
    public static void closeFtp(){
        if (ftp !=null && ftp.isConnected()) {
            try {
                ftp.logout();
                ftp.disconnect();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    
    /**
     * ftp上传文件
     * @param f
     * @throws Exception
     */
    public static void upload(File f) throws Exception{
    	boolean flag = false;
    	
        if (f.isDirectory()) {
        	flag = ftp.makeDirectory(f.getName());
        	if(!flag) throw new RuntimeException("create dir fail");
        	
        	flag = ftp.changeWorkingDirectory(f.getName());
            if(!flag) throw new RuntimeException("change dir fail");
            
            String[] files = f.list();
            for(String fstr : files){
                File file1 = new File(f.getPath()+"/"+fstr);
                if (file1.isDirectory()) {
                    upload(file1);
                    ftp.changeToParentDirectory();
                }else{
                    File file2=new File(f.getPath()+"/"+fstr);
                    FileInputStream input=new FileInputStream(file2);
                    ftp.storeFile(file2.getName(), input);
                    input.close();
                }
            }
        }else{
            File file2 = new File(f.getPath());
            FileInputStream input=new FileInputStream(file2);
            ftp.storeFile(file2.getName(),input);
            input.close();
        }
    }
    
    /**
     * 下载链接配置
     * @param f
     * @param localBaseDir 本地目录
     * @param remoteBaseDir 远程目录
     * @throws Exception
     */
    public static Set<String> startDownload(FtpConfig config,String localBaseDir,String remoteBaseDir ) throws Exception{
    	Set<String> fileNameSet = null;
        if (FtpUtil.connectFtp(config)) {
            try { 
            	logger.info("邮件存放路径:[{}]", remoteBaseDir);
                FTPFile[] files = null; 
                boolean changedir = ftp.changeWorkingDirectory(remoteBaseDir); 
                File localFile=new File(localBaseDir);
                if(!localFile.exists()){
                	localFile.mkdirs();
                }
                if (changedir) {
                    ftp.setControlEncoding(config.getEncode()); 
                    files = ftp.listFiles(); 
                    
                    for (int i = 0; i < files.length; i++) {
                    
                    	if(!files[i].getName().equals(".")&&!files[i].getName().equals("..")){
                    		logger.error("文件名字{}", files[i].getName());
                    		  try{
                              	fileNameSet = downloadFile(files[i], localBaseDir, remoteBaseDir); 
                              }catch(Exception e){
                                  logger.error("<"+files[i].getName()+">下载失败", e); 
                              } 
                    			
                    	}
                    
                      
                    } 
                } 
            } catch (Exception e) { 
                logger.error("下载过程中出现异常:[{}]", e); 
            } 
        }else{
            logger.error("链接失败！");
        }
        
        return fileNameSet;
    }
    
    
    /** 
     * 
     * 下载FTP文件 
     * 当你需要下载FTP文件的时候，调用此方法 
     * 根据<b>获取的文件名，本地地址，远程地址</b>进行下载 
     * 
     * @param ftpFile 
     * @param relativeLocalPath 
     * @param relativeRemotePath 
     * @return List<String> 文件名列表
     */ 
    private  static Set<String> downloadFile(FTPFile ftpFile, String relativeLocalPath,String relativeRemotePath) {
    	Set<String> filePathList = null;
    	
        if (ftpFile.isFile()) {
            if (ftpFile.getName().indexOf("?") == -1) {
            	filePathList = new HashSet<>();
                OutputStream outputStream = null;
                
                try {
                	String fileName = relativeLocalPath+ ftpFile.getName();
                	filePathList.add(fileName);
                	
                    File locaFile= new File(fileName); 
                    //判断文件是否存在，存在则不处理 
                    if(!locaFile.exists()){
                        outputStream = new FileOutputStream(fileName); 
                        ftp.retrieveFile(ftpFile.getName(), outputStream); 
                        outputStream.flush(); 
                        outputStream.close(); 
                    } 
                } catch (Exception e) { 
                    logger.error("下载文件异常", e);
                } finally { 
                    try { 
                        if (outputStream != null){ 
                            outputStream.close(); 
                        }
                    } catch (IOException e) { 
                       logger.error("输出文件流异常"); 
                    }
                }
                
            }
        } else {
            String newlocalRelatePath = relativeLocalPath + ftpFile.getName(); 
            String newRemote = new String(relativeRemotePath+ ftpFile.getName().toString()); 
            File fl = new File(newlocalRelatePath); 
            if (!fl.exists()) { 
                fl.mkdirs(); 
            } 
            try { 
                newlocalRelatePath = newlocalRelatePath + '/'; 
                newRemote = newRemote + "/"; 
                String currentWorkDir = ftpFile.getName().toString(); 
                boolean changedir = ftp.changeWorkingDirectory(currentWorkDir); 
                if (changedir) {
                    FTPFile[] files = null; 
                    files = ftp.listFiles(); 
                    for (int i = 0; i < files.length; i++) { 
                        downloadFile(files[i], newlocalRelatePath, newRemote); 
                    } 
                } 
                if (changedir){
                    ftp.changeToParentDirectory(); 
                } 
            } catch (Exception e) { 
                logger.error("下载FTP文件 异常", e);
            } 
        }
        
        return filePathList;
    } 
}
